package utils

import (
	"bytes"
	"crypto/md5"
	"crypto/rand"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"text/template"
)

// Int String转为int类型
func Int(s string) int {
	if s == "" {
		return 0
	}
	value, err := strconv.Atoi(s)
	if err != nil {
		return 0
	}
	return value
}

func Find(array []interface{}, item interface{}) (index int) {
	index = -1
	for idx, value := range array {
		if value == item {
			index = idx
			break
		}
	}
	return
}

// Render 解析模板
func Render(data map[string]string, content string) (body string, err error) {
	var buf bytes.Buffer

	if temp, err := template.New("").Option("missingkey=zero").Parse(content); err == nil {
		if err := temp.Execute(&buf, data); err == nil {
			content = buf.String()
			return content, nil
		} else {
			return content, err
		}
	} else {
		return content, err
	}
}

// InArray 查找字符是否在数组中
func InArray(obj interface{}, target interface{}) bool {
	targetValue := reflect.ValueOf(target)
	switch reflect.TypeOf(target).Kind() {
	case reflect.Slice, reflect.Array:
		for i := 0; i < targetValue.Len(); i++ {
			if targetValue.Index(i).Interface() == obj {
				return true
			}
		}
	case reflect.Map:
		if targetValue.MapIndex(reflect.ValueOf(obj)).IsValid() {
			return true
		}
	}

	return false
}

func CamelCaseToSnakeCase(str string) string {
	if str == "" {
		return str
	}
	strLen := len(str)
	result := make([]byte, 0, strLen*2)
	j := false
	for i := 0; i < strLen; i++ {
		char := str[i]
		if i > 0 && char >= 'A' && char <= 'Z' && j {
			result = append(result, '_')
		}
		if char != '_' {
			j = true
		}
		result = append(result, char)
	}
	str = strings.ToLower(string(result))
	return str
}

func MarshalJSON(v interface{}) []byte {
	// Regexp definitions
	var keyMatchRegex = regexp.MustCompile(`\"(\w+)\":`)
	var wordBarrierRegex = regexp.MustCompile(`(\w)([A-Z])`)
	marshalled, err := json.Marshal(v)
	if err != nil {

	}
	converted := keyMatchRegex.ReplaceAllFunc(
		marshalled,
		func(match []byte) []byte {
			return bytes.ToLower(wordBarrierRegex.ReplaceAll(
				match,
				[]byte(`${1}_${2}`),
			))
		},
	)
	return converted
}

func ToCamelCase(underscore string) string {
	words := strings.Split(underscore, "_")

	for i := 1; i < len(words); i++ {
		words[i] = strings.Title(words[i])
	}

	return strings.Join(words, "")
}

func GetMobileEncrypt(mobile string) string {
	if len(mobile) > 7 {
		return mobile[:3] + "****" + mobile[7:]
	} else if len(mobile) > 3 {
		return mobile[:3] + "****"
	}
	return mobile
}
func GetContactNameEncrypt(name string) string {
	first := string([]rune(name)[0:1])
	return first + "**"
}

func MD5(s string) string {
	sum := md5.Sum([]byte(s))
	return hex.EncodeToString(sum[:])
}

// RandomNumber 生成长度为 length 随机数字字符串
func RandomNumber(length int) string {
	table := [...]byte{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}
	b := make([]byte, length)
	n, err := io.ReadAtLeast(rand.Reader, b, length)
	if n != length {
		panic(err)
	}
	for i := 0; i < len(b); i++ {
		b[i] = table[int(b[i])%len(table)]
	}
	return string(b)
}

// SplitStr 以空格，顿号，中英文逗号分割字符串
func SplitStr(str string) (result []string) {
	strings.TrimSpace(str)
	if str == "" {
		return result
	}
	// 1.处理空格 " "
	arr := strings.Split(str, " ")
	for _, s1 := range arr {
		if s1 == "" {
			continue
		}
		// 2.处理顿号 "、"
		arr2 := strings.Split(s1, "、")
		for _, s2 := range arr2 {
			if s2 == "" {
				continue
			}
			// 3.处理中文逗号 "，"
			arr3 := strings.Split(s2, "，")
			for _, s3 := range arr3 {
				if s3 == "" {
					continue
				}
				arr4 := strings.Split(s3, ",")
				for _, s4 := range arr4 {
					if s4 == "" {
						continue
					}
					result = append(result, s4)
				}
			}
		}
	}

	return result
}

// Decimal 保留n位小数点
func Decimal(str string, n string) (float32, error) {
	f, err := strconv.ParseFloat(str, 64)
	if err != nil {
		return 0, err
	}

	f1, errF := strconv.ParseFloat(fmt.Sprintf("%."+n+"f", f), 64)
	if errF != nil {
		return 0, err
	}
	return float32(f1), nil
}

// DecimalFloat 保留2位小数点
func DecimalFloat(str float32) (float32, error) {
	f1, errF := strconv.ParseFloat(fmt.Sprintf("%.2f", str), 64)
	if errF != nil {
		return 0, errF
	}
	return float32(f1), nil
}

func MyStructToMap(data interface{}) map[string]interface{} {
	result := make(map[string]interface{})
	structValue := reflect.ValueOf(data)
	structType := structValue.Type()

	for i := 0; i < structType.NumField(); i++ {
		field := structType.Field(i)
		fieldName := field.Tag.Get("json")

		fieldValue := structValue.Field(i).Interface()
		result[fieldName] = fieldValue

		// Handle nested structs
		if field.Type.Kind() == reflect.Struct {
			nestedMap := MyStructToMap(fieldValue)
			for key, value := range nestedMap {
				result[key] = value
			}
		}

		// Handle slices
		if field.Type.Kind() == reflect.Slice {
			sliceValue := reflect.ValueOf(fieldValue)
			for j := 0; j < sliceValue.Len(); j++ {
				sliceElement := sliceValue.Index(j).Interface()
				if sliceElement != nil {
					if _, isMap := sliceElement.(map[string]interface{}); isMap {
						result[fmt.Sprintf("%s[%d]", fieldName, j)] = sliceElement
					}
				}
			}
		}
	}

	return result
}

// SplitString 字符串拆分
func SplitString(input string, separator string) (string, string, error) {
	lastIndex := strings.LastIndex(input, separator)

	if lastIndex == -1 {
		// 如果找不到分隔符，返回错误
		return "", "", fmt.Errorf("分隔符 %s 不存在于字符串中", separator)
	}

	firstPart := input[:lastIndex]
	secondPart := input[lastIndex+len(separator):]

	return firstPart, secondPart, nil
}

// GetDateOnly 获取 2001-01-01 00:00:00 的 2001-01-01格式
func GetDateOnly(str string) string {
	if len(str) >= 10 {
		return str[:10]
	} else {
		return str
	}
}
